#ifndef __DAP_CONFIG_H__
#define __DAP_CONFIG_H__

#define CPU_CLOCK               SystemCoreClock ///< Specifies the CPU Clock in Hz

#define IO_PORT_WRITE_CYCLES    1               ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0

#define DAP_DEFAULT_SWJ_CLOCK   10000000        ///< Default SWD/JTAG clock frequency in Hz.
//**************************************************************************************************
/**
JTAG I/O Pin                 | SWD I/O Pin          | CMSIS-DAP Hardware pin mode
---------------------------- | -------------------- | ---------------------------------------------
TCK: Test Clock              | SWCLK: Clock         | Output Push/Pull
TMS: Test Mode Select        | SWDIO: Data I/O      | Output Push/Pull; Input (for receiving data)
TDI: Test Data Input         |                      | Output Push/Pull
TDO: Test Data Output        |                      | Input
nTRST: Test Reset (optional) |                      | Output Open Drain with pull-up resistor
nRESET: Device Reset         | nRESET: Device Reset | Output Open Drain with pull-up resistor

DAP Hardware I/O Pin Access Functions
*/
#include "sys.h"
#include "DAP_config.h"
#include "DAP.h"

// Configure DAP I/O pins1 ------------------------------
#define SWD_GPIO   				GPIOI
#define PIN_SWCLK_1  			GPIO_PIN_0
#define PIN_SWDIO_1   			GPIO_PIN_8
#define PIN_nRESET_1  			GPIO_PIN_9

// Configure DAP I/O pins2 ------------------------------
#define PIN_SWCLK_2  			GPIO_PIN_5
#define PIN_SWDIO_2   			GPIO_PIN_6
#define PIN_nRESET_2  			GPIO_PIN_7

// Configure DAP I/O pins3 ------------------------------
#define PIN_SWCLK_3  			GPIO_PIN_1
#define PIN_SWDIO_3   			GPIO_PIN_3
#define PIN_nRESET_3  			GPIO_PIN_4

static __inline uint32_t TIMESTAMP_GET (void) {
  return (DWT->CYCCNT);
}



//-------------------------------------------------------------------------------------
/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
 - SWCLK, SWDIO, nRESET to output mode and set to default high level.
*/
static void PORT_SWD_SETUP_1(void)
{
	GPIO_InitTypeDef GPIO_Initure;

	__HAL_RCC_GPIOI_CLK_ENABLE();

	GPIO_Initure.Pin = PIN_SWCLK_1 | PIN_SWDIO_1 | PIN_nRESET_1;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;  
	GPIO_Initure.Pull = GPIO_PULLUP;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);

	HAL_GPIO_WritePin(SWD_GPIO, PIN_SWCLK_1, GPIO_PIN_SET);	
	HAL_GPIO_WritePin(SWD_GPIO, PIN_SWDIO_1, GPIO_PIN_SET);	
	HAL_GPIO_WritePin(SWD_GPIO, PIN_nRESET_1, GPIO_PIN_SET);
}

/** Disable JTAG/SWD I/O Pins.
 - TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
*/
static void PORT_OFF_1(void)
{
	GPIO_InitTypeDef GPIO_Initure;

	GPIO_Initure.Pin = PIN_SWCLK_1 | PIN_SWDIO_1 | PIN_nRESET_1;
	GPIO_Initure.Mode = GPIO_MODE_INPUT;  
	GPIO_Initure.Pull = GPIO_NOPULL;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);
}

// SWCLK/TCK I/O pin -------------------------------------

// Current status of the SWCLK/TCK DAP hardware I/O pin
static __inline uint32_t PIN_SWCLK_TCK_IN_1(void)
{
    return (SWD_GPIO->ODR & PIN_SWCLK_1) ? 1 : 0;
}

static __inline void PIN_SWCLK_TCK_SET_1(void)
{
	SWD_GPIO->BSRR = PIN_SWCLK_1;
}

static __inline void PIN_SWCLK_TCK_CLR_1(void)
{
	SWD_GPIO->BSRR = (uint32_t)PIN_SWCLK_1 << 16;
}

// SWDIO/TMS Pin I/O --------------------------------------

// Current status of the SWDIO/TMS DAP hardware I/O pin
static __inline uint32_t PIN_SWDIO_TMS_IN_1(void)
{
	return (SWD_GPIO->ODR & PIN_SWDIO_1) ? 1 : 0;
}

static __inline void PIN_SWDIO_TMS_SET_1(void)
{
	SWD_GPIO->BSRR = PIN_SWDIO_1;
}

static __inline void PIN_SWDIO_TMS_CLR_1(void)
{
	SWD_GPIO->BSRR = (uint32_t)PIN_SWDIO_1 << 16;
}

static __inline uint32_t PIN_SWDIO_IN_1(void)
{
    return (SWD_GPIO->IDR & PIN_SWDIO_1) ? 1 : 0;
}

static __inline void PIN_SWDIO_OUT_1(uint32_t bit)
{
    if(bit & 1) SWD_GPIO->BSRR = PIN_SWDIO_1;
    else        SWD_GPIO->BSRR = (uint32_t)PIN_SWDIO_1 << 16;
}

static __inline void PIN_SWDIO_OUT_ENABLE_1(void)
{
	GPIO_InitTypeDef GPIO_Initure;		

	GPIO_Initure.Pin = PIN_SWDIO_1;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;  
	GPIO_Initure.Pull = GPIO_PULLUP;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);
}

static __inline void PIN_SWDIO_OUT_DISABLE_1(void)
{
	GPIO_InitTypeDef GPIO_Initure;

	GPIO_Initure.Pin = PIN_SWDIO_1;
	GPIO_Initure.Mode = GPIO_MODE_INPUT;  
	GPIO_Initure.Pull = GPIO_NOPULL;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);
}

// nRESET Pin I/O------------------------------------------
static __inline uint32_t PIN_nRESET_IN_1(void)
{
	return 0;
}

static __inline void PIN_nRESET_OUT_1(uint32_t bit)
{
    if(bit & 1) SWD_GPIO->BSRR = PIN_nRESET_1;	
    else        SWD_GPIO->BSRR = (uint32_t)PIN_nRESET_1 << 16;
}






//**************************************************************************************************
/** Connect LED: is active when the DAP hardware is connected to a debugger
    Running LED: is active when program execution in target started
*/

static __inline void LED_CONNECTED_OUT(uint32_t bit)
{

}

static __inline void LED_RUNNING_OUT(uint32_t bit)
{

}

static void DAP_SETUP_1(void)
{
	PORT_OFF_1();
}

static uint32_t RESET_TARGET(void)
{
    return (0);              // change to '1' when a device reset sequence is implemented
}


//********************************************************************************


/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
 - SWCLK, SWDIO, nRESET to output mode and set to default high level.
*/
static void PORT_SWD_SETUP_2(void)
{
	GPIO_InitTypeDef GPIO_Initure;

	__HAL_RCC_GPIOI_CLK_ENABLE();

	GPIO_Initure.Pin = PIN_SWCLK_2 | PIN_SWDIO_2 | PIN_nRESET_2;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;  
	GPIO_Initure.Pull = GPIO_PULLUP;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);

	HAL_GPIO_WritePin(SWD_GPIO, PIN_SWCLK_2, GPIO_PIN_SET);	
	HAL_GPIO_WritePin(SWD_GPIO, PIN_SWDIO_2, GPIO_PIN_SET);	
	HAL_GPIO_WritePin(SWD_GPIO, PIN_nRESET_2, GPIO_PIN_SET);
}

/** Disable JTAG/SWD I/O Pins.
 - TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
*/
static void PORT_OFF_2(void)
{
	GPIO_InitTypeDef GPIO_Initure;

	GPIO_Initure.Pin = PIN_SWCLK_2 | PIN_SWDIO_2 | PIN_nRESET_2;
	GPIO_Initure.Mode = GPIO_MODE_INPUT;  
	GPIO_Initure.Pull = GPIO_NOPULL;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);
}

// SWCLK/TCK I/O pin -------------------------------------

// Current status of the SWCLK/TCK DAP hardware I/O pin
static __inline uint32_t PIN_SWCLK_TCK_IN_2(void)
{
    return (SWD_GPIO->ODR & PIN_SWCLK_2) ? 1 : 0;
}

static __inline void PIN_SWCLK_TCK_SET_2(void)
{
	SWD_GPIO->BSRR = PIN_SWCLK_2;
}

static __inline void PIN_SWCLK_TCK_CLR_2(void)
{
	SWD_GPIO->BSRR = (uint32_t)PIN_SWCLK_2 << 16;
}

// SWDIO/TMS Pin I/O --------------------------------------

// Current status of the SWDIO/TMS DAP hardware I/O pin
static __inline uint32_t PIN_SWDIO_TMS_IN_2(void)
{
	return (SWD_GPIO->ODR & PIN_SWDIO_2) ? 1 : 0;
}

static __inline void PIN_SWDIO_TMS_SET_2(void)
{
	SWD_GPIO->BSRR = PIN_SWDIO_2;
}

static __inline void PIN_SWDIO_TMS_CLR_2(void)
{
	SWD_GPIO->BSRR = (uint32_t)PIN_SWDIO_2 << 16;
}

static __inline uint32_t PIN_SWDIO_IN_2(void)
{
    return (SWD_GPIO->IDR & PIN_SWDIO_2) ? 1 : 0;
}

static __inline void PIN_SWDIO_OUT_2(uint32_t bit)
{
    if(bit & 1) SWD_GPIO->BSRR = PIN_SWDIO_2;
    else        SWD_GPIO->BSRR = (uint32_t)PIN_SWDIO_2 << 16;
}

static __inline void PIN_SWDIO_OUT_ENABLE_2(void)
{
	GPIO_InitTypeDef GPIO_Initure;		

	GPIO_Initure.Pin = PIN_SWDIO_2;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;  
	GPIO_Initure.Pull = GPIO_PULLUP;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);
}

static __inline void PIN_SWDIO_OUT_DISABLE_2(void)
{
	GPIO_InitTypeDef GPIO_Initure;

	GPIO_Initure.Pin = PIN_SWDIO_2;
	GPIO_Initure.Mode = GPIO_MODE_INPUT;  
	GPIO_Initure.Pull = GPIO_NOPULL;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);
}

// nRESET Pin I/O------------------------------------------
static __inline uint32_t PIN_nRESET_IN_2(void)
{
	return 0;
}

static __inline void PIN_nRESET_OUT_2(uint32_t bit)
{
    if(bit & 1) SWD_GPIO->BSRR = PIN_nRESET_2;	
    else        SWD_GPIO->BSRR = (uint32_t)PIN_nRESET_2 << 16;
}


//**************************************************************************************************
/** Connect LED: is active when the DAP hardware is connected to a debugger
    Running LED: is active when program execution in target started
*/

static __inline void LED_CONNECTED_OUT_2(uint32_t bit)
{

}

static __inline void LED_RUNNING_OUT_2(uint32_t bit)
{

}

static void DAP_SETUP_2(void)
{
	PORT_OFF_2();
}

static uint32_t RESET_TARGET_2(void)
{
    return (0);              // change to '1' when a device reset sequence is implemented
}

//********************************************************************************

/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
 - SWCLK, SWDIO, nRESET to output mode and set to default high level.
*/
static void PORT_SWD_SETUP_3(void)
{
	GPIO_InitTypeDef GPIO_Initure;

	__HAL_RCC_GPIOI_CLK_ENABLE();

	GPIO_Initure.Pin = PIN_SWCLK_3 | PIN_SWDIO_3 | PIN_nRESET_3;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;  
	GPIO_Initure.Pull = GPIO_PULLUP;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);

	HAL_GPIO_WritePin(SWD_GPIO, PIN_SWCLK_3, GPIO_PIN_SET);	
	HAL_GPIO_WritePin(SWD_GPIO, PIN_SWDIO_3, GPIO_PIN_SET);	
	HAL_GPIO_WritePin(SWD_GPIO, PIN_nRESET_3, GPIO_PIN_SET);
}

/** Disable JTAG/SWD I/O Pins.
 - TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
*/
static void PORT_OFF_3(void)
{
	GPIO_InitTypeDef GPIO_Initure;

	GPIO_Initure.Pin = PIN_SWCLK_3 | PIN_SWDIO_3 | PIN_nRESET_3;
	GPIO_Initure.Mode = GPIO_MODE_INPUT;  
	GPIO_Initure.Pull = GPIO_NOPULL;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);
}

// SWCLK/TCK I/O pin -------------------------------------

// Current status of the SWCLK/TCK DAP hardware I/O pin
static __inline uint32_t PIN_SWCLK_TCK_IN_3(void)
{
    return (SWD_GPIO->ODR & PIN_SWCLK_3) ? 1 : 0;
}

static __inline void PIN_SWCLK_TCK_SET_3(void)
{
	SWD_GPIO->BSRR = PIN_SWCLK_3;
}

static __inline void PIN_SWCLK_TCK_CLR_3(void)
{
	SWD_GPIO->BSRR = (uint32_t)PIN_SWCLK_3 << 16;
}

// SWDIO/TMS Pin I/O --------------------------------------

// Current status of the SWDIO/TMS DAP hardware I/O pin
static __inline uint32_t PIN_SWDIO_TMS_IN_3(void)
{
	return (SWD_GPIO->ODR & PIN_SWDIO_3) ? 1 : 0;
}

static __inline void PIN_SWDIO_TMS_SET_3(void)
{
	SWD_GPIO->BSRR = PIN_SWDIO_3;
}

static __inline void PIN_SWDIO_TMS_CLR_3(void)
{
	SWD_GPIO->BSRR = (uint32_t)PIN_SWDIO_3 << 16;
}

static __inline uint32_t PIN_SWDIO_IN_3(void)
{
    return (SWD_GPIO->IDR & PIN_SWDIO_3) ? 1 : 0;
}

static __inline void PIN_SWDIO_OUT_3(uint32_t bit)
{
    if(bit & 1) SWD_GPIO->BSRR = PIN_SWDIO_3;
    else        SWD_GPIO->BSRR = (uint32_t)PIN_SWDIO_3 << 16;
}

static __inline void PIN_SWDIO_OUT_ENABLE_3(void)
{
	GPIO_InitTypeDef GPIO_Initure;		

	GPIO_Initure.Pin = PIN_SWDIO_3;
	GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;  
	GPIO_Initure.Pull = GPIO_PULLUP;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);
}

static __inline void PIN_SWDIO_OUT_DISABLE_3(void)
{
	GPIO_InitTypeDef GPIO_Initure;

	GPIO_Initure.Pin = PIN_SWDIO_3;
	GPIO_Initure.Mode = GPIO_MODE_INPUT;  
	GPIO_Initure.Pull = GPIO_NOPULL;          
	GPIO_Initure.Speed = GPIO_SPEED_FAST;     
	HAL_GPIO_Init(SWD_GPIO, &GPIO_Initure);
}

// nRESET Pin I/O------------------------------------------
static __inline uint32_t PIN_nRESET_IN_3(void)
{
	return 0;
}

static __inline void PIN_nRESET_OUT_3(uint32_t bit)
{
    if(bit & 1) SWD_GPIO->BSRR = PIN_nRESET_3;	
    else        SWD_GPIO->BSRR = (uint32_t)PIN_nRESET_3 << 16;
}


//**************************************************************************************************
/** Connect LED: is active when the DAP hardware is connected to a debugger
    Running LED: is active when program execution in target started
*/

static __inline void LED_CONNECTED_OUT_3(uint32_t bit)
{

}

static __inline void LED_RUNNING_OUT_3(uint32_t bit)
{

}

static void DAP_SETUP_3(void)
{
	PORT_OFF_3();
}

static uint32_t RESET_TARGET_3(void)
{
    return (0);              // change to '1' when a device reset sequence is implemented
}


#endif // __DAP_CONFIG_H__
